<?php

/**
 * Project form base class.
 *
 * @package    portfolio
 * @subpackage form
 * @author     Your name here
 * @version    SVN: $Id: sfDoctrineFormBaseTemplate.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
abstract class BaseFormDoctrine extends sfFormDoctrine
{

  /**
   * Setups the current form.
   *
   * @see configure()
   */
  public function setup()
  {
    if ($this->getObject()->getTable()->hasTemplate('Doctrine_Template_NestedSet')) {
      $this->configureDoctrineTemplateNestedSet();
    }
  }

  /**
   * Updates and saves the current object. Overrides the parent method
   * by treating the record as a node in the nested set and updating
   * the tree accordingly.
   *
   * @param Doctrine_Connection $con An optional connection parameter
   */
  public function doSave($con = null)
  {
    // save the record itself
    if ($this->getObject()->getTable()->hasTemplate('Doctrine_Template_NestedSet')) {
      $this->doSaveDoctrineTemplateNestedSet($con);
    }

    parent::doSave($con);
  }

  /* ------------ PRIVATES  ------------ */

  // Doctrine_Template_NestedSet
  private function configureDoctrineTemplateNestedSet()
  {
    unset($this['lft'], $this['rgt'], $this['level']);

    // create a new widget to represent this category's "parent"
    $this->setWidget('parent', new sfWidgetFormDoctrineChoiceNestedSet(array(
        'model' => $this->getModelName(),
        'add_empty' => true,
      )));

    // if the current category has a parent, make it the default choice
    if ($this->getObject()->getNode()->hasParent()) {
      $this->setDefault('parent', $this->getObject()->getNode()->getParent()->getId());
    }

    // set a validator for parent which prevents a category being moved to one of its own descendants
    $this->setValidator('parent', new sfValidatorDoctrineChoiceNestedSet(array(
        'required' => true,
        'model' => $this->getModelName(),
        'node' => $this->getObject(),
      )));
    $this->getValidator('parent')->setMessage('node', 'A category cannot be made a descendent of itself.');
  }

  // Doctrine_Template_NestedSet
  private function doSaveDoctrineTemplateNestedSet($con = null)
  {
    // if a parent has been specified, add/move this node to be the child of that node
    if ($this->getValue('parent')) {
      $node = $this->getObject()->getNode();
      $parent = Doctrine::getTable($this->getModelName())->findOneById($this->getValue('parent'));

      if ($this->isNew()) {
        $node->insertAsLastChildOf($parent);
      }
      elseif (!$node->isDescendantOf($parent)) {
        $node->moveAsLastChildOf($parent);
      }
    }
  }

}
